﻿
using System;
using System.ServiceModel;
using System.ServiceModel.Channels;

using WSU.Cheka.HelloWCF.Contracts;

namespace WSU.Cheka.HelloWCF.Client
{
    sealed class WsuClient : ClientBase<IWsuContract>, IWsuContract
    {
        #region "constructor"

        /// <summary>
        /// for building client proxy via codes
        /// </summary>
        public WsuClient(Binding binding, string remoteAddress)
            : base(binding, new EndpointAddress(remoteAddress))
        { }

        /// <summary>
        /// for building client proxy via configuration
        /// </summary>
        public WsuClient(string endpntCfgName)
            : base(endpntCfgName)
        { }

        #endregion

        #region "implement contract interface"

        public string[] GetDepartments()
        {
            return base.Channel.GetDepartments();
        }

        public int GetNumberByDepartment(string departName)
        {
            return base.Channel.GetNumberByDepartment(departName);
        }

        public void AddDepartment(string departName, int number)
        {
            base.Channel.AddDepartment(departName, number);
        }

        #endregion
    }

    static class TestWsuClient
    {
        private const string TcpEndpntAddress = "net.tcp://localhost:9000/wsu";
        private const string PipeEndpntAddress = "net.pipe://localhost/wsu";

        /// <summary>
        /// pay attenttion, below codes only for test, because it is not a good design
        /// each service operation is too fine-grained, which results in too much communication overhead
        /// </summary>
        public static void Invoke(this IWsuContract proxy)
        {
            string[] departNames = proxy.GetDepartments();
            foreach (string name in departNames)
            {
                Console.WriteLine("Department<{0}> has {1} people", name, proxy.GetNumberByDepartment(name));
            }
        }

        private static void CallViaCodes()
        {
            using (WsuClient tcpProxy = new WsuClient(new NetTcpBinding(), TcpEndpntAddress))
            {
                tcpProxy.Invoke();
                Console.WriteLine("******************* TCP proxy invoked.");
            }

            using (WsuClient pipeProxy = new WsuClient(new NetNamedPipeBinding(), PipeEndpntAddress))
            {
                pipeProxy.Invoke();
                Console.WriteLine("******************* Named Pipe proxy invoked.");
            }
        }

        private static void CallViaConfig()
        {
            using (WsuClient tcpProxy = new WsuClient("WsuTcpClient"))
            {
                tcpProxy.Invoke();
                Console.WriteLine("=================== TCP proxy invoked.");
            }

            using (WsuClient pipeProxy = new WsuClient("WsuNamedPipeClient"))
            {
                pipeProxy.Invoke();
                Console.WriteLine("=================== Named Pipe proxy invoked.");
            }
        }

        public static void TestMain()
        {
            CallViaCodes();
            CallViaConfig();
        }
    }
}